package org.chmodke.proxy.socks.server;

import org.chmodke.proxy.socks.util.C;
import org.chmodke.proxy.socks.util.U;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 数据转发
 *
 * @author kehao
 */
public class Transfer implements Runnable {
    private static final Logger logger = LoggerFactory.getLogger(Transfer.class);
    private final AtomicBoolean alive;
    private final InputStream in;
    private final OutputStream out;

    public Transfer(InputStream in, OutputStream out, AtomicBoolean alive) {
        this.alive = alive;
        this.in = in;
        this.out = out;
    }

    @Override
    public void run() {
        logger.info("{} Transfer start,from:{} to:{}", C.PROXY_LOG, in, out);
        long dataLen = 0L;
        byte[] buffer = new byte[1024];
        int len;
        try {
            while (alive.get() && (len = in.read(buffer)) > 0) {
                logger.debug("{} Transfer doing,from:{} to:{}, count:{}.", C.PROXY_LOG, in, out, len);
                dataLen += len;
                out.write(buffer, 0, len);
                out.flush();
            }
        } catch (Exception e) {
            logger.error("{} Transfer error", C.PROXY_LOG);
        } finally {
            logger.info("{} Transfer end,from:{} to:{}, count:{}.", C.PROXY_LOG, in, out, dataLen);
            alive.compareAndSet(true, false);
            destroy();
        }
    }

    public void destroy() {
        logger.info("{} close socket, system cleaning ...", C.PROXY_LOG);
        U.closeIo(out);
        U.closeIo(in);
    }
}
